<?php

namespace App\Console\Commands\Article;

use App\Models\Article\ArticleCategoryModel;
use App\Models\Article\Category\ArticleCategoryOperateDailyStatisticsModel;
use App\Models\Article\Category\ArticleCategoryOperateHistoryModel;
use App\Models\Article\Category\ArticleCategoryOperateResultModel;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class CategoryDailyStatisticsCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'article:categoryDailyStatistics {whichDay?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '专题每日统计汇总';

    /**
     * @var string|null
     */
    protected ?string $date = null;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle(): int
    {
        $this->date = $this->input->getArgument("whichDay") ?? date("Y-m-d", strtotime("-1 day", time()));
        $dailyGroup = ArticleCategoryOperateHistoryModel::query()
                                                        ->with([
                                                            "categoryRel" => function ($query) {
                                                                $query->withoutGlobalScope("isDel");
                                                            }
                                                        ])
                                                        ->where("createdAt", ">=", strtotime($this->date))
                                                        ->where("createdAt", "<",
                                                            strtotime("+1 day", strtotime($this->date)))
                                                        ->groupBy(["targetId", "operateType", "status"])
                                                        ->select([
                                                            "targetId",
                                                            "operateType",
                                                            "status",
                                                            DB::raw("count(*) as total")
                                                        ])
                                                        ->get();

        $insertData = [];
        $dailyGroup->groupBy(["targetId", "operateType"])->each(function ($row, int $targetId) use (&$insertData) {
            $row->each(function ($operateDetail, int $operateType) use (&$insertData, $targetId) {
                $increaseNum = attributeGet(
                    $operateDetail->where("status", ArticleCategoryOperateResultModel::STATUS_SUCCESS)->first(),
                    "total",
                    0
                );
                $cancelNum   = attributeGet(
                    $operateDetail->where("status", ArticleCategoryOperateResultModel::STATUS_CANCEL)->first(),
                    "total",
                    0
                );
                $prefix      = ArticleCategoryOperateResultModel::ALL_OPERATE_TYPE_PREFIX[$operateType] . "Num";
                array_push($insertData, [
                    "date"        => $this->date,
                    "targetId"    => $targetId,
                    "operateType" => $operateType,
                    "increaseNum" => $increaseNum,
                    "cancelNum"   => $cancelNum,
                    "netNum"      => $increaseNum - $cancelNum,
                    "totalNum"    => collect($operateDetail)->getIterator()->current()->categoryRel->$prefix,
                    "createdAt"   => time()
                ]);

            });
        });

        $allCollect = collect($insertData);
        collect(array_merge(array_keys(ArticleCategoryOperateResultModel::OPERATE_TYPE_TEXT),
            [ArticleCategoryOperateResultModel::OPERATE_TYPE_CATEGORY]))->each(function (int $operateType) use (
            $allCollect,
            &$insertData
        ) {
            switch ($operateType) {
                case ArticleCategoryOperateResultModel::OPERATE_TYPE_CATEGORY:
                    $totalNum = ArticleCategoryModel::query()->count();
                    break;
                default:
                    $prefix   = ArticleCategoryOperateResultModel::OPERATE_TYPE_PREFIX[$operateType] . "Num";
                    $totalNum = ArticleCategoryModel::query()->sum($prefix);
                    break;
            }

            array_push($insertData, [
                "date"        => $this->date,
                "targetId"    => 0,
                "operateType" => $operateType,
                "increaseNum" => $allCollect->where("operateType", $operateType)->sum("increaseNum"),
                "cancelNum"   => $allCollect->where("operateType", $operateType)->sum("cancelNum"),
                "netNum"      => $allCollect->where("operateType", $operateType)->sum("netNum"),
                "totalNum"    => $totalNum,
                "createdAt"   => time()
            ]);
        });


        ArticleCategoryOperateDailyStatisticsModel::query()->insert($insertData);

        return 0;
    }
}
